﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "GbmpElevationView.h"
#include "DbObjectUtils.h"
#include "GbmpBuiltInModelViewDeletionComponent.h"
#include "GbmpBuiltInParameterDefinitions.h"
#include "GbmpElevationViewInput.h"
#include "GbmpModelViewExternalDataId.h"
#include "GbmpModelViewUtil.h"
#include "ICopyStrategyReporter.h"
#include "IDocument.h"
#include "IElementParentReporter.h"
#include "IElevationViewSymbolNew.h"
#include "IExternalDataComponent.h"
#include "IModelView.h"
#include "IParameter.h"
#include "IParameterDefinitionLibrary.h"
#include "IWorkPlane.h"
#include "IUserCoordinateSystem.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"
using namespace gcmp;

DEFINE_MODEL_VIEW_BASE_METHODS(GbmpElevationView)

DBOBJECT_DATA_DEFINE(GbmpElevationView)
{
    m_pOwnerElement = nullptr;
}

GbmpElevationView* GbmpElevationView::Create(const GbmpElevationViewInput& input)
{
    IModelView* pModelView = GbmpModelViewUtil::CreateModelView(input.Document, input.Name, BuiltInViewType::TwoDimensional,
        input.ViewDirection, input.Origin, input.RightDirection, input.UpDirection);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");
    pModelView->SetUserDataId(input.ViewType);

    if (input.HasRectViewport)
    {
        pModelView->CreateDefaultRectViewport(input.RectViewportWidth / 2.0, input.RectViewportWidth / 2.0, input.RectViewportHeight / 2.0, input.RectViewportHeight / 2.0);
    }

    if (input.IsBuiltIn)
    {
        pModelView->SetElementDeletionComponent(NEW_AS_OWNER_PTR(GbmpBuiltInModelViewDeletionComponent));
    }

    IElevationViewSymbolNew::Create(input.Document, pModelView->GetElementId());

    IUserCoordinateSystem* pUCS = IUserCoordinateSystem::Create(input.Document, input.Name, input.Origin, input.RightDirection, input.UpDirection);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUCS, L"pUCS为空",L"GDMPLab",L"2024-03-30");

    GbmpElevationView* pElevationView = GbmpElevationView::RegisterExternalData(pModelView);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElevationView, L"pElevationView为空",L"GDMPLab",L"2024-03-30");

    pElevationView->SetUserViewTypeName(input.ViewType);

    pModelView->BindUserCoordinateSystem(pUCS->GetElementId());

    return pElevationView;
}

GbmpElevationView* GbmpElevationView::Get(IModelView* pModelView)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    if (IExternalDataComponent * pExternalDataComponent = pModelView->GetExternalDataComponent())
    {
        IExternalData* pData = pExternalDataComponent->FindExternalData(MODEL_VIEW_EXTERNAL_DATA_ID);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pData, L"pData为空",L"GDMPLab",L"2024-03-30");
        return quick_cast<GbmpElevationView>(pData);
    }
    return nullptr;
}

const GbmpElevationView* GbmpElevationView::Get(const IModelView* pModelView)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    if (const IExternalDataComponent * pExternalDataComponent = pModelView->GetExternalDataComponent())
    {
        const IExternalData* pData = pExternalDataComponent->FindExternalData(MODEL_VIEW_EXTERNAL_DATA_ID);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pData, L"pData为空",L"GDMPLab",L"2024-03-30");
        return quick_cast<const GbmpElevationView>(pData);
    }
    return nullptr;
}

GbmpElevationView* GbmpElevationView::RegisterExternalData(IModelView* pModelView)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView, L"pModelView为空",L"GDMPLab",L"2024-03-30");

    OwnerPtr<GbmpElevationView> opElevationView = NEW_AS_OWNER_PTR(GbmpElevationView);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opElevationView, L"opElevationView为空",L"GDMPLab",L"2024-03-30");

    opElevationView->SetOwnerElement(pModelView);

    GbmpElevationView* pElevationView = opElevationView.get();
    if (IExternalDataComponent * pExternalDataComponent = pModelView->GetExternalDataComponent())
    {
        pExternalDataComponent->RegisterExternalData(MODEL_VIEW_EXTERNAL_DATA_ID, TransferOwnership(opElevationView));
        return pElevationView;
    }
    return nullptr;
}

void GbmpElevationView::UpdateForWeakParentDeletion(const std::set<ElementId>& deletedElementIds)
{
}

void GbmpElevationView::ReportParents(IElementParentReporter& reporter) const
{
}

void GbmpElevationView::GetCalculators(ICalculatorCollection * calculators) const
{
}

void GbmpElevationView::ReportParameterDefinitions(std::vector<int>* pParamDefIds) const
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pParamDefIds, L"pParamDefIds为空",L"GDMPLab",L"2024-03-30");
}

OwnerPtr<IParameter> GbmpElevationView::GetNativeParameter(int paramDefId) const
{
    return nullptr;
}

bool GbmpElevationView::SetNativeParameter(const IParameter *param, std::wstring* errorMsg/* = nullptr*/)
{
    return false;
}

bool GbmpElevationView::IsParameterModifiable(int paramDefId) const
{
    return true;
}

void GbmpElevationView::Report(const ICopyContext& copyContext, ICopyStrategyReporter& reporter) const
{
    reporter.ReportToCopy(GetOwnerElementId());
}

IDocument* GbmpElevationView::GetDocument() const
{
    return m_pOwnerElement ? m_pOwnerElement->GetDocument() : nullptr;
}

ElementId GbmpElevationView::GetOwnerElementId() const
{
    return m_pOwnerElement ? m_pOwnerElement->GetElementId() : ElementId::InvalidID;
}

NdbObject* GbmpElevationView::GetTopOwnerObject() const
{
    if (!GetDocument())
        return nullptr;

    return quick_cast<NdbObject>(GetDocument()->GetElement(GetOwnerElementId()));
}
